/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package br.ufg.inf.pos.bd;

import br.ufg.inf.pos.br.utils.ConnectionFactory;
import br.ufg.inf.pos.br.utils.RegraDaoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author luan
 */
public class ProdutoDaoImpl implements ProdutoDao{
    
    private Connection connection = null;
    private Statement statement = null;
    private PreparedStatement preparedStatement = null;
    private ResultSet resultSet = null;

    private final String COLUMN_NOME = "NOMEPRODUTO";
    private final String COLUMN_DESCRICAO = "DESCRICAO";
    private final String COLUMN_MARCA = "MARCAPRODUTO";
    private final String COLUMN_MODELO = "MODELOPRODUTO";
    private final String COLUMN_CATEGORIA = "CATEGORIA_IDCATEGORIA";
    private final String COLUMN_IDPRODUTO = "IDPRODUTO";


    @Override
    public int salvar(Produto produto) throws RegraDaoException{
      
        int codigoInserido = 0;
        try {
            connection = ConnectionFactory.getConnection();
             preparedStatement = connection
                    .prepareStatement("insert into produto("+COLUMN_NOME+","+COLUMN_DESCRICAO+","
               + ""+COLUMN_MARCA+","+COLUMN_MODELO+","+COLUMN_CATEGORIA+") values (?,?,?,?,?)",new String[]{COLUMN_IDPRODUTO});
            preparedStatement.setString(1, produto.getNome());
            preparedStatement.setString(2, produto.getDescricao());
            preparedStatement.setString(3, produto.getMarca());
            preparedStatement.setString(4, produto.getModelo());
            preparedStatement.setInt(5, produto.getCategoria().getCodigoCategoria());
            
             if (preparedStatement.executeUpdate() > 0) {
                resultSet = preparedStatement.getGeneratedKeys();
                if (null != resultSet && resultSet.next()) {
                    codigoInserido = resultSet.getInt(1);
                }
            }
        } catch (SQLException ex) {
           throw new RegraDaoException(ex.getSQLState());
        } finally {
            close();
            return codigoInserido;
        }
    }


    @Override
    public List<Produto> getAll() {
        List<Produto> produtos = new ArrayList<>();
           CategoriaDao categoriaDao = new CategoriaDaoImpl();
        try {
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(
                       "select * from produto order by produto."+COLUMN_NOME+"");
            while (resultSet.next()) {
               Produto produtoLido = new Produto();
                try {
                    produtoLido.setCategoria(categoriaDao.getByCode(resultSet.getInt(COLUMN_CATEGORIA), connection));
                  } catch (RegraDaoException ex) {
                    connection.rollback();
                    throw new RegraDaoException("Não foi possível recuperar a categoria");
                }
                produtoLido.setIdProduto(resultSet.getInt(COLUMN_IDPRODUTO));
                produtoLido.setDescricao(resultSet.getString(COLUMN_DESCRICAO));
                produtoLido.setMarca(resultSet.getString(COLUMN_MARCA));
                produtoLido.setModelo(resultSet.getString(COLUMN_MODELO));
                produtoLido.setNome(resultSet.getString(COLUMN_NOME));
            produtos.add(produtoLido);
            }
        } catch (SQLException ex) {
            throw new RegraDaoException("Erro ao recuperar objeto: "
                    + ex.getMessage());
        } catch (ClassNotFoundException ex) {
            throw new RegraDaoException("Erro ao conectar-se ao banco: "
                    + ex.getMessage());
        } finally {
            close();
        }
        
        return produtos;
    }

    @Override
    public void atualizar(String nomeProduto, Produto produto) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void remover(Produto produto) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public DefaultTableModel listarCategoriaJtable() throws RegraDaoException{
   DefaultTableModel tabelaModelo = new DefaultTableModel();
   tabelaModelo.setColumnIdentifiers(new String[]{"Nome", "Descrição",
       "Marca","Modelo","Categoria" });
            int posicao = 0;
        try {
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(
                    "select * from produto order by produto."+COLUMN_NOME+"");
            while(resultSet.next()){
                tabelaModelo.insertRow(posicao, new Object[]{
                    resultSet.getString(COLUMN_NOME), resultSet.getString(COLUMN_DESCRICAO),
                    resultSet.getString(COLUMN_MARCA),resultSet.getString(COLUMN_MODELO),
                resultSet.getInt(COLUMN_CATEGORIA)});
                posicao++;
            }
        } catch (SQLException ex) {
            throw new RegraDaoException("Erro ao recuperar objeto: "
                    + ex.getMessage());
        } finally {
            close();
            return tabelaModelo;
        }
        
    }

    // you need to close all three to make sure
    private void close() {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException("Erro ao fechar");
        }

    }
    
    
    
    @Override
    public Produto getByName(String nomeProduto) {
        Produto produto = null;
        CategoriaDao categoriaDao = new CategoriaDaoImpl();
      try {
            connection = ConnectionFactory.getConnection();
            preparedStatement = connection
                    .prepareStatement("select * from produto where produto." + COLUMN_NOME + " = ? ");
            connection.setAutoCommit(false);
            preparedStatement.setString(1, nomeProduto);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                produto = new Produto();
                try {
                    produto.setCategoria(categoriaDao.getByCode(resultSet.getInt(COLUMN_CATEGORIA), connection));
                  } catch (RegraDaoException ex) {
                    connection.rollback();
                    throw new RegraDaoException("Não foi possível recuperar a categoria");
                }
                produto.setIdProduto(resultSet.getInt(COLUMN_IDPRODUTO));
                produto.setDescricao(resultSet.getString(COLUMN_DESCRICAO));
                produto.setMarca(resultSet.getString(COLUMN_MARCA));
                produto.setModelo(resultSet.getString(COLUMN_MODELO));
                produto.setNome(resultSet.getString(COLUMN_NOME));
            }
       } catch (SQLException ex) {
             connection.rollback();
            throw new RuntimeException("Erro ao recuperar objeto: "
                    + ex.getMessage());
        } catch (ClassNotFoundException ex) {
             connection.rollback();
            throw new RuntimeException("Erro ao conectar-se ao banco: "
                    + ex.getMessage());
        } catch (RegraDaoException ex) {
             connection.rollback();
            throw new RuntimeException(ex.getMessage());
        } finally {
            try {
                connection.commit();
                connection.setAutoCommit(true);
          } catch (SQLException ex) {
                throw new RegraDaoException("Não foi possivel finalizar transação" + ex.getMessage());
            }
            close();
            return produto;
        }
   
    
    }

    @Override
    public Produto getByName(String nomeProduto, Connection conn) {
    Produto produto = null;
        CategoriaDao categoriaDao = new CategoriaDaoImpl();
      try {
            preparedStatement = conn
                    .prepareStatement("select * from produto where produto." + COLUMN_NOME + " = ? ");
            preparedStatement.setString(1, nomeProduto);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                produto = new Produto();
                try {
                    produto.setCategoria(categoriaDao.getByCode(resultSet.getInt(COLUMN_CATEGORIA), conn));
                  } catch (RegraDaoException ex) {
                    conn.rollback();
                    throw new RegraDaoException("Não foi possível recuperar a categoria");
                }
                produto.setIdProduto(resultSet.getInt(COLUMN_IDPRODUTO));
                produto.setDescricao(resultSet.getString(COLUMN_DESCRICAO));
                produto.setMarca(resultSet.getString(COLUMN_MARCA));
                produto.setModelo(resultSet.getString(COLUMN_MODELO));
                produto.setNome(resultSet.getString(COLUMN_NOME));
            }
       } catch (SQLException ex) {
             conn.rollback();
           throw new RuntimeException("Erro ao recuperar objeto: "
                    + ex.getMessage());
        } catch (RegraDaoException ex) {
             conn.rollback();
            throw new RuntimeException(ex.getMessage());
        } finally {
            return produto;
        }
    
    }
    
    
}
